home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xlock / spline.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-09  |  7.5 KB  |  277 lines

  1. #ifndef lint
  2. static char sccsid[] = "@(#)spline.c   93/01/20 XLOCK";
  3. #endif
  4.  
  5. /*  spline.c - Bouncing Spline for xlock, the X Window System lockscreen
  6.  *
  7.  *  Copyright (c) 1993 by Cor Bosman. (bosman@fwi.uva.nl)
  8.  *
  9.  *  See xlock.c for copying information.
  10.  *
  11.  *  21-Jan-93: Converted kurvp1 and kurvp2 to C from pascal.
  12.  *  20-Jan-93: Written.
  13.  */
  14.  
  15. #include "xlock.h"
  16. #include <stdio.h>
  17. #include <math.h>
  18.  
  19. #define CURVEPOINTS 200  /* number of points on the curve */
  20. #define SIGMA 1.0
  21. #define MAXLINES 1000
  22.  
  23. typedef struct {
  24.     XPoint points[CURVEPOINTS+1];
  25. } curve;
  26.  
  27. typedef struct {
  28.     int npoints;
  29.     int nlines;  
  30.     int pix;
  31.     double *x;
  32.     double *y;
  33.     int *dx;
  34.     int *dy;
  35.     int head;
  36.     int tail;
  37.     int width;
  38.     int height;
  39.     long startTime;
  40.     curve *curves;
  41.     double *xp;
  42.     double *yp;
  43. } splinestruct;
  44.  
  45. static splinestruct splines[MAXSCREENS];
  46.  
  47. void
  48. initspline(win)
  49. Window win;
  50. {
  51.   int i;
  52.  
  53.   XWindowAttributes xgwa;
  54.   splinestruct *sp = &splines[screen];
  55.  
  56.   sp->startTime = seconds();
  57.   if(points < 2) points=2;
  58.   else if(points > 20) points=20;
  59.   sp->npoints = points;
  60.   if(batchcount > MAXLINES) batchcount = MAXLINES;
  61.   sp->nlines = batchcount+1;
  62.  
  63.   if(!sp->curves) {
  64.     sp->x = (double *) malloc(sizeof(double) * sp->npoints);
  65.     sp->y = (double *) malloc(sizeof(double) * sp->npoints);
  66.     sp->dx = (int *) malloc(sizeof(int) * sp->npoints);
  67.     sp->dy = (int *) malloc(sizeof(int) * sp->npoints);
  68.     sp->xp = (double *) malloc(sizeof(double) * sp->npoints);
  69.     sp->yp = (double *) malloc(sizeof(double) * sp->npoints);
  70.     sp->curves = (curve *) malloc(sizeof(curve) * sp->nlines);
  71.   }
  72.   memset(sp->curves, 0, sp->nlines * sizeof(curve));
  73.   
  74.   XGetWindowAttributes(dsp, win, &xgwa);
  75.   sp->width = xgwa.width;
  76.   sp->height = xgwa.height;
  77.  
  78.   if(sp->width < 100) sp->nlines = 2;
  79.  
  80.   srand(time(NULL));
  81.   for(i=0; i<sp->npoints; i++) {
  82.     sp->x[i] = (double)(rand() % sp->width);
  83.     sp->y[i] = (double)(rand() % sp->height);
  84.     sp->dx[i] = ((rand()%21)-10);
  85.     while(sp->dx[i] == 0) sp->dx[i] = ((rand()%21)-10);
  86.     sp->dy[i] = ((rand()%21)-10);
  87.     while(sp->dy[i] == 0) sp->dy[i] = ((rand()%21)-10);
  88.   }  
  89.   sp->head = 0;
  90.   sp->tail = 1;
  91.   XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp,screen));
  92.   XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, sp->width, sp->height);
  93. }
  94.  
  95. void
  96. drawspline(win) 
  97. Window win;
  98. {
  99.   double s;
  100.   splinestruct *sp = &splines[screen];
  101.   int i;
  102.   
  103.   for(i=0; i<sp->npoints; i++) {
  104.     sp->x[i] += sp->dx[i];
  105.     sp->y[i] += sp->dy[i];
  106.     if((sp->x[i]<0) || (sp->x[i]>sp->width)) sp->dx[i] = -sp->dx[i];
  107.     if((sp->y[i]<0) || (sp->y[i]>sp->height)) sp->dy[i] = -sp->dy[i];
  108.   }
  109.   kurvp1(sp->npoints, sp->x, sp->y, SIGMA, sp->xp, sp->yp, &s);
  110.   for(i=0; i<CURVEPOINTS; i++) {
  111.     kurvp2((double)i/CURVEPOINTS,s,SIGMA,sp->npoints,sp->x,sp->y,sp->xp,sp->yp,
  112.        &(sp->curves[sp->head].points[i].x),&(sp->curves[sp->head].points[i].y));
  113.   }
  114.  
  115.   XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[sp->pix]);
  116.  
  117.   sp->curves[sp->head].points[CURVEPOINTS].x = sp->curves[sp->head].points[0].x;
  118.   sp->curves[sp->head].points[CURVEPOINTS].y = sp->curves[sp->head].points[0].y;
  119.  
  120.   XDrawLines(dsp, win, Scr[screen].gc, sp->curves[sp->head].points, CURVEPOINTS+1, CoordModeOrigin);
  121.  
  122.   sp->head++;  if(sp->head >= sp->nlines) sp->head = 0;
  123.  
  124.   sp->curves[sp->tail].points[CURVEPOINTS].x = sp->curves[sp->tail].points[0].x;
  125.   sp->curves[sp->tail].points[CURVEPOINTS].y = sp->curves[sp->tail].points[0].y;
  126.  
  127.   XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen));
  128.   XDrawLines(dsp,win,Scr[screen].gc,sp->curves[sp->tail].points,CURVEPOINTS+1,CoordModeOrigin);
  129.   sp->tail++;  if(sp->tail >= sp->nlines) sp->tail = 0;
  130.  
  131.   if(++sp->pix >= Scr[screen].npixels) sp->pix = 0;
  132. }  
  133.  
  134.  
  135. /* kurvp1 and kurvp2 create the kurve through a number of points */
  136. kurvp1(n, x, y, sigma, xp, yp, s) 
  137. int n;
  138. double *x, *y, sigma, *xp, *yp, *s;
  139. /*
  140.  *  Adapted from A.K. Cline, Comm. ACM 4 (1972) 220
  141.  */
  142. {
  143.     int nm1,np1,i,ip1,ibak;
  144.     double delx1,delx2,dels1,dx1,dy1,dely1,dely2,dels2,dx2,dy2, sigmap,exps,sinhs,sinhin,diag1,diag2,diagin,spdig1,spdiag,dels;
  145.     double temp[CURVEPOINTS*2];
  146.  
  147.     nm1 = n-2; np1=n;
  148.     delx1 = x[1]-x[0];
  149.     dely1 = y[1]-y[0];
  150.     dels1 = sqrt(pow(delx1, 2.0)+pow(dely1, 2.0));
  151.     dx1 = delx1/dels1; dy1 = dely1/dels1;
  152.     xp[0] = dx1; yp[0] = dy1;
  153.     temp[0] = dels1;
  154.     *s = dels1;
  155.     
  156.     for(i=1; i<n; i++) {
  157.       if(i == n-1) ip1 = 0;
  158.       else ip1 = i+1;
  159.       delx2 = x[ip1]-x[i]; dely2=y[ip1]-y[i];
  160.       dels2 = sqrt(pow(delx2, 2.0) + pow(dely2, 2.0));
  161.       dx2 = delx2/dels2;
  162.       dy2 = dely2/dels2;
  163.       xp[i] = dx2-dx1;  yp[i]=dy2-dy1;
  164.       temp[i] = dels2;
  165.       delx1 = delx2;  dely1=dely2;  dels1=dels2;
  166.       dx1 = dx2; dy1 = dy2;
  167.       (*s)=(*s)+dels1;
  168.     }
  169.  
  170.     xp[0] = xp[0]-dx1;  yp[0]=yp[0]-dy1;
  171.     sigmap = fabs(sigma)*(n/(*s));
  172.    
  173.     dels = sigmap*temp[n-1];  exps = exp(dels);
  174.     sinhs = 0.5*(exps-(1.0/exps));
  175.     sinhin = 1.0/(temp[n-1]*sinhs);
  176.     diag1 = sinhin*(dels*0.5*(exps+(1.0/exps))-sinhs);
  177.     diagin = 1.0/diag1;
  178.     spdig1 = sinhin*(sinhs-dels);
  179.     spdiag = 0;
  180.     
  181.     for(i=0; i<n; i++) {
  182.       dels = sigmap*temp[i];
  183.       exps = exp(dels);
  184.       sinhs = 0.5*(exps-(1.0/exps));
  185.       sinhin = 1.0/(temp[i]*sinhs);
  186.       diag2 = sinhin*(dels*(0.5*(exps+(1.0/exps)))-sinhs);
  187.       
  188.       if(i == 0) {
  189.         diagin = 1.0/(diag1+diag2);
  190.         xp[0] = diagin*xp[0];
  191.         yp[0] = diagin*yp[0];
  192.         temp[n] = 0;
  193.         temp[np1] = -diagin*spdig1;
  194.         spdiag = sinhin*(sinhs-dels);
  195.         temp[0] = diagin*spdiag;
  196.         diag1 = diag2;
  197.       }
  198.       if((i<n-1) && (i>0)) {
  199.         diagin = 1.0/(diag1+diag2-(spdiag*temp[i-1]));
  200.         xp[i] = diagin*(xp[i]-(spdiag*xp[i-1]));
  201.         yp[i] = diagin*(yp[i]-(spdiag*yp[i-1]));
  202.         temp[n+i] = -diagin*temp[nm1+i+1]*spdiag;
  203.         spdiag = sinhin*(sinhs-dels);
  204.         temp[i] = diagin*spdiag;
  205.         diag1 = diag2;
  206.       }
  207.     }
  208.  
  209.     temp[nm1] = temp[n+nm1]-temp[nm1];
  210.     
  211.     if(n!=2) {
  212.       for(i=2; i<n; i++) {
  213.         ibak = np1-i-1;
  214.         xp[ibak] = xp[ibak]-temp[ibak]*xp[ibak+1];
  215.         yp[ibak] = yp[ibak]-temp[ibak]*yp[ibak+1];
  216.         temp[ibak] = temp[ibak+n] - temp[ibak]*temp[ibak+1];
  217.       }
  218.     }
  219.     xp[n-1] = (xp[n-1]-(spdig1*xp[0])-(spdiag*xp[nm1]))/
  220.               (diag1+diag2+(spdig1*temp[0])+(spdiag*temp[nm1]));
  221.     yp[n-1] = (yp[n-1]-(spdig1*yp[0])-(spdiag*yp[nm1]))/
  222.               (diag1+diag2+(spdig1*temp[0])+(spdiag*temp[nm1]));
  223.    
  224.     for(i=0; i<=nm1; i++) {
  225.       xp[i] = xp[i] + (temp[i]*xp[n-1]);
  226.       yp[i] = yp[i] + (temp[i]*yp[n-1]);
  227.     }
  228. }
  229.  
  230. kurvp2(t, s, sigma, n, x, y, xp, yp, xs, ys)
  231. double t, s, sigma;
  232. int n;
  233. double *x, *y, *xp, *yp;
  234. short *xs, *ys;
  235. /*
  236.  *  Adapted from A.K. Cline, Comm. ACM 4 (1974) 220
  237.  */
  238. {
  239.   int flag, i, im1;
  240.   double sigmap, tn, delx, dely, dels, del1, del2, sum, sumdels, savesum, exps, exps1, sinhs, sinhd1, sinhd2;
  241.  
  242.  
  243.   sigmap=fabs(sigma)*(n/s);
  244.   tn=fabs(t*s); i=1; sum=0;
  245.   do {
  246.     delx=x[i]-x[i-1];
  247.     dely=y[i]-y[i-1];
  248.     dels=sqrt((delx*delx)+(dely*dely));
  249.     sumdels=sum+dels;
  250.     flag=(sumdels>=tn);
  251.     savesum=sum;
  252.     sum=sumdels;
  253.     i++;
  254.   } while(!(flag || (i==n))); 
  255.   if(flag) {
  256.     sum=savesum;
  257.     i--;
  258.     im1=i-1;
  259.   } else {
  260.     i=0;
  261.     im1=n-1;
  262.     dels=s-sum;
  263.   }
  264.   del1=tn-sum; del2=dels-del1;
  265.   exps1=exp(sigmap*del1);
  266.   sinhd1=0.5*(exps1-1.0/exps1);
  267.   exps=exp(sigmap*del2);
  268.   sinhd2=0.5*(exps-1.0/exps);
  269.   exps=exps1*exps;
  270.   sinhs=0.5*(exps-1.0/exps);
  271.   *xs=(short)((xp[i]*sinhd1+xp[im1]*sinhd2)/sinhs +
  272.          ((x[i]-xp[i])*del1+(x[im1]-xp[im1])*del2)/dels);
  273.   *ys=(short)((yp[i]*sinhd1+yp[im1]*sinhd2)/sinhs +
  274.          ((y[i]-yp[i])*del1+(y[im1]-yp[im1])*del2)/dels);
  275. }
  276.  
  277.